package com.fhao.system.service.sysuser.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fhao.common.core.constants.Constants;
import com.fhao.common.core.constants.HttpConstants;
import com.fhao.common.core.domain.LoginUser;
import com.fhao.common.core.domain.R;
import com.fhao.common.core.domain.vo.LoginUserVo;
import com.fhao.common.core.enums.ResultCode;
import com.fhao.common.core.enums.UserIdentity;
import com.fhao.common.redis.service.RedisService;
import com.fhao.common.security.exception.ServiceException;
import com.fhao.common.security.service.TokenService;
import com.fhao.system.domain.sysuser.SysUser;
import com.fhao.system.domain.sysuser.dto.SysUserSaveDTO;
import com.fhao.system.mapper.sysuser.SysUserMapper;
import com.fhao.system.service.sysuser.ISysUserService;
import com.fhao.system.utils.BCryptUtils;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RefreshScope
public class SysUserServiceImpl implements ISysUserService {

    @Resource
    private SysUserMapper sysUserMapper;

    @Value("${jwt.secret}") //配置在Nacos上
    private String secret;

    @Resource
    private TokenService tokenService;

    @Resource
    private RedisService redisService;

    @Override
    public R<String> login(String userAccount, String password) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        SysUser sysUser = sysUserMapper.selectOne
                (queryWrapper.select(SysUser::getUserId, SysUser::getPassword, SysUser::getNickName)
                        .eq(SysUser::getUserAccount, userAccount));
//        R loginResult = new R();
//        int a = 100/0;
        if(sysUser == null) {
//            loginResult.setCode(ResultCode.FAILED_USER_NOT_EXISTS.getCode());
//            loginResult.setMsg(ResultCode.FAILED_USER_NOT_EXISTS.getMsg());
//            return loginResult;
            return R.fail(ResultCode.FAILED_USER_NOT_EXISTS);
        }

        if(!BCryptUtils.matchesPassword(password, sysUser.getPassword())) {
//            loginResult.setCode(ResultCode.FAILED_LOGIN.getCode());
//            loginResult.setMsg(ResultCode.FAILED_LOGIN.getMsg());
//            return loginResult;
            return R.fail(ResultCode.FAILED_LOGIN);
        }
        String token = tokenService.createToken(sysUser.getUserId(), secret, UserIdentity.ADMIN.getValue(),sysUser.getNickName(),null);
        return R.ok(token);
        //用户携带jwt, 利用 jwt中的userKey拿到redis的value值,如果value不为空说明当前还在有效时间内,否则反之.

    }

    @Override
    public int add(SysUserSaveDTO sysUserSaveDTO) {
        //将 dto 转为实体 (如果还需要将dto转为实体,那干嘛不直接使用实体呢?)
        List<SysUser> sysUserList = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUserAccount, sysUserSaveDTO.getUserAccount()));
        if(CollectionUtil.isNotEmpty(sysUserList)) {
            //用户已存在
            //需要自定义异常
            throw new ServiceException(ResultCode.AILED_USER_EXISTS);
        }
        SysUser sysUser = new SysUser();
        sysUser.setUserAccount(sysUserSaveDTO.getUserAccount());
        sysUser.setPassword(BCryptUtils.encryptPassword(sysUserSaveDTO.getPassword()));
        sysUser.setCreateBy(Constants.SYSTEM_USER_ID);
        return sysUserMapper.insert(sysUser);
    }

    @Override
    public R<LoginUserVo> info(String token) {
        // 如果前端设置了令牌前缀，则裁剪掉前缀
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        LoginUser loginUser = tokenService.getLoginUser(token, secret);
        //校验loginUser
        if(loginUser == null) {
            return R.fail();
        }
        LoginUserVo loginUserVo = new LoginUserVo();
        loginUserVo.setNickName(loginUser.getNickName());
        return R.ok(loginUserVo);
    }

    @Override
    public boolean logout(String token) {
        // 如果前端设置了令牌前缀，则裁剪掉前缀
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        return tokenService.deleteLoginUser(token, secret);
    }
}














